package com.hunttown.mes.manage.controller._basic;

import com.hunttown.mes.manage.controller.common.AdminBaseClass;
import com.hunttown.mes.rpc.domain.*;
import com.hunttown.mes.rpc.domain.enums.mes.produce.*;
import com.hunttown.mes.rpc.domain.enums.purchase.ProductTypeEnum;
import com.hunttown.mes.rpc.domain.enums.task.PriorityTypeEnum;
import com.hunttown.mes.rpc.domain.enums.workflow.ApplyLineStatusEnum;
import com.hunttown.mes.rpc.domain.enums.workflow.ApplyStatusEnum;
import com.hunttown.mes.rpc.domain.enums.workflow.ApprovalTypeEnum;
import com.hunttown.mes.rpc.domain.enums.workflow.BusinessTypeEnum;
import com.hunttown.mes.rpc.domain.enums.purchase.PurchaseDetailOutEnum;
import com.hunttown.mes.rpc.domain.enums.pay.ReceiveWayEnum;
import com.hunttown.common.domain.Page;
import com.hunttown.mes.manage.controller.common.ModelService;
import com.hunttown.mes.manage.service.*;
import com.hunttown.mes.rpc.domain.query.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;

/**
 * @title: 流程审批
 * @author: wangjunfu
 * @date: 2019-08-01 16:55:14
 * @description:
 */
@Controller
@RequestMapping(value = "/basic/wfapplyline")
public class WFApplyLineController {

    private final static Logger logger = LoggerFactory.getLogger(WFApplyLineController.class);

    private final ModelService modelService;
    private final AnalysisManageManageService manageService;
    private final AnalysisCatalogManageService catalogService;
    private final WorkflowApplyManageService applyService;
    private final WorkflowApplyLineManageService applyLineService;
    private final WorkflowApplyLineUserManageService lineUserService;
    private final WorkflowBusinessManageService businessService;
    private final TransactionService transactionService;
    private final TransportExpenseManageService expenseService;
    private final TransportExpenseDetailManageService expenseDetailService;
    private final TransportPurchaseInventoryManageService inventoryService;
    private final TransportPurchaseInventoryDetailManageService inventoryDetailService;
    private final TransportPurchaseManageService purchaseService;
    private final TransportPurchaseDetailManageService purchaseDetailService;
    private final TransportPurchaseDocManageService purchaseDocService;
    private final TransportPurchaseOutManageService purchaseOutService;
    private final TransportTableChineseEnglishManageService chineseEnglishService;
    private final TransportUserManageService userService;
    private final TransportUploadFilesManageService uploadFilesService;
    private final MesSaleOrderManageService mesSaleOrderService;
    private final MesSaleOrderDetailManageService mesSaleOrderDetailService;
    private final MesOrderMaterialManageService mesOrderMaterialService;
    private final MesProduceOrderManageService mesProduceOrderService;
    private final MesProduceOrderSaleManageService mesProduceOrderSaleService;

    @Autowired
    public WFApplyLineController(ModelService modelService, AnalysisManageManageService manageService, AnalysisCatalogManageService catalogService, WorkflowApplyManageService applyService, WorkflowApplyLineManageService applyLineService, WorkflowApplyLineUserManageService lineUserService, WorkflowBusinessManageService businessService, TransactionService transactionService, TransportExpenseManageService expenseService, TransportExpenseDetailManageService expenseDetailService, TransportPurchaseInventoryManageService inventoryService, TransportPurchaseInventoryDetailManageService inventoryDetailService, TransportPurchaseManageService purchaseService, TransportPurchaseDetailManageService purchaseDetailService, TransportPurchaseDocManageService purchaseDocService, TransportPurchaseOutManageService purchaseOutService, TransportTableChineseEnglishManageService chineseEnglishService, TransportUserManageService userService, TransportUploadFilesManageService uploadFilesService, MesSaleOrderManageService mesSaleOrderService, MesSaleOrderDetailManageService mesSaleOrderDetailService, MesOrderMaterialManageService mesOrderMaterialService, MesProduceOrderManageService mesProduceOrderService, MesProduceOrderSaleManageService mesProduceOrderSaleService){
        this.modelService = modelService;
        this.manageService = manageService;
        this.catalogService = catalogService;
        this.applyService = applyService;
        this.applyLineService = applyLineService;
        this.lineUserService = lineUserService;
        this.businessService = businessService;
        this.transactionService = transactionService;
        this.expenseService = expenseService;
        this.expenseDetailService = expenseDetailService;
        this.inventoryService = inventoryService;
        this.inventoryDetailService = inventoryDetailService;
        this.purchaseService = purchaseService;
        this.purchaseDetailService = purchaseDetailService;
        this.purchaseDocService = purchaseDocService;
        this.purchaseOutService = purchaseOutService;
        this.chineseEnglishService = chineseEnglishService;
        this.userService = userService;
        this.uploadFilesService = uploadFilesService;
        this.mesSaleOrderService = mesSaleOrderService;
        this.mesSaleOrderDetailService = mesSaleOrderDetailService;
        this.mesOrderMaterialService = mesOrderMaterialService;
        this.mesProduceOrderService = mesProduceOrderService;
        this.mesProduceOrderSaleService = mesProduceOrderSaleService;
    }

    //region 审批（通用）

    /**
     * 审批（通用）
     *
     * @param model   model模型
     * @param applyId 申请流程主键id
     * @return vm
     */
    @RequestMapping(value = "/approval-line", method = RequestMethod.GET)
    public String index(HttpServletRequest request, Model model, Integer applyId) {
        if (applyId == null || applyId == 0) {
            throw new RuntimeException("未查询到审批流程信息");
        }

        //审批ID
        model.addAttribute("applyId", applyId);

        //region STEP 01.获取申请信息
        WorkflowApplyDTO applyDTO = applyService.getById(applyId);
        if (applyDTO == null) {
            throw new RuntimeException("未查询到审批流程信息");
        }
        applyDTO.setApplyName(modelService.getManageName(applyDTO.getApply()));
        applyDTO.setStatusName(ApplyStatusEnum.getEnumByKey(applyDTO.getStatus()));
        model.addAttribute("applyObj", applyDTO);

        String pin = AdminBaseClass.getPin(request);
        AnalysisManageDTO curr_obj = manageService.getFromCachePin(pin);
        //endregion

        //region STEP 02.获取流程业务信息
        WorkflowBusinessDTO businessDTO = businessService.getById(applyDTO.getBusinessId());
        if (businessDTO == null) {
            throw new RuntimeException("未查询到流程业务信息");
        }
        businessDTO.setBusinessTypeName(BusinessTypeEnum.getEnumByKey(businessDTO.getBusinessType()));
        model.addAttribute("businessObj", businessDTO);
        //endregion

        //region STEP 03.获取具体申请业务信息
        TransportTableChineseEnglishDTO englishDTO = chineseEnglishService.getById(applyDTO.getTableId());
        if (englishDTO == null) {
            throw new RuntimeException("未查询到数据库表信息");
        }

        //region [3].报销
        if (englishDTO.getTableName().toLowerCase().equals("transport_expense")) {
            TransportExpenseDTO expenseDTO = expenseService.getById(applyDTO.getRecordId());
            expenseDTO.setBxTypeName(businessDTO.getBusinessName());
            expenseDTO.setBxProjectName(modelService.getCatalogName(expenseDTO.getBxProject()));
            expenseDTO.setAdminName(modelService.getManageName(expenseDTO.getAdminId()));
            expenseDTO.setBxPeopleCn(modelService.getUserTrueName(expenseDTO.getBxPeople()));
            expenseDTO.setReviewerCn(modelService.getUserTrueName(expenseDTO.getReviewer()));

            //收款单位
            expenseDTO.setCompanyName(modelService.getCompanyName(expenseDTO.getCompanyId()));

            //付款公司
            expenseDTO.setPayCompanyName(modelService.getCompanyName(expenseDTO.getPayCompanyId()));

            //付款方式
            expenseDTO.setPayWayName(ReceiveWayEnum.getEnumByKey(expenseDTO.getPayWay()));

            model.addAttribute("bxObj", expenseDTO);

            //region 当前申请人的借款信息
            //条件：已完成审批、关联ID 一致
            TransportExpenseDTOQuery applyQuery = new TransportExpenseDTOQuery();
            applyQuery.setBxType(6);
            applyQuery.setBxStatus(2);
            applyQuery.setRelationId(expenseDTO.getId());
            applyQuery.setPageSize(100);
            Page<TransportExpenseDTO> applyPage = expenseService.getForPage(applyQuery);
            for (TransportExpenseDTO item : applyPage.getItems()) {
                item.setBxProjectName(modelService.getCatalogName(item.getBxProject()));
                item.setBxPeopleCn(modelService.getUserTrueName(item.getBxPeople()));
            }
            model.addAttribute("applyPage", applyPage);
            //endregion

            //region 当前申请人的支付信息
            TransportExpenseDTOQuery payQuery = new TransportExpenseDTOQuery();
            payQuery.setBxType(7);
            payQuery.setBxStatus(2);
            payQuery.setRelationId(expenseDTO.getId());
            payQuery.setPageSize(100);
            Page<TransportExpenseDTO> payPage = expenseService.getForPage(payQuery);
            for (TransportExpenseDTO item : payPage.getItems()) {
                item.setBxProjectName(modelService.getCatalogName(item.getBxProject()));
                item.setBxPeopleCn(modelService.getUserTrueName(item.getBxPeople()));
            }
            model.addAttribute("payPage", payPage);
            //endregion

            //【司机报销】

            //【采购报销】【配件报销】
            if (expenseDTO.getBxType() == 2 || expenseDTO.getBxType() == 3) {
                TransportPurchaseDetailDTOQuery detailDTOQuery = new TransportPurchaseDetailDTOQuery();
                detailDTOQuery.setBxId(expenseDTO.getId());
                detailDTOQuery.setPageSize(1000);
                Page<TransportPurchaseDetailDTO> dataPage = purchaseDetailService.getForPage(detailDTOQuery);

                BigDecimal total = new BigDecimal(0); //总计
                AnalysisManageDTO manageDTO;
                for (TransportPurchaseDetailDTO item : dataPage.getItems()) {
                    manageDTO = manageService.getFromCacheId(item.getrPurchaser());
                    item.setrPurchaserName(manageDTO.getNickName());
                    item.setPartName(modelService.getPurchaseName(item.getPartId()));

                    total = total.add(item.getrAmount());
                }

                model.addAttribute("purchasePage", dataPage);
                model.addAttribute("total", total);
            }
        }
        //endregion

        //region [4].配件盘点
        if (englishDTO.getTableName().toLowerCase().equals("transport_purchase_inventory")) {
            TransportPurchaseInventoryDTO inventoryDTO = inventoryService.getById(applyDTO.getRecordId());
            inventoryDTO.setInventoryCn(modelService.getManageName(inventoryDTO.getInventory()));
            inventoryDTO.setReviewerCn(modelService.getManageName(inventoryDTO.getReviewer()));
            model.addAttribute("inventoryObj", inventoryDTO);

            //获取盘点明细
            TransportPurchaseInventoryDetailDTOQuery detailDTOQuery = new TransportPurchaseInventoryDetailDTOQuery();
            detailDTOQuery.setInventoryId(applyDTO.getRecordId());
            detailDTOQuery.setStopFlag(0);
            detailDTOQuery.setPageSize(1000);
            Page<TransportPurchaseInventoryDetailDTO> dataPage = inventoryDetailService.getForPage(detailDTOQuery);
            for (TransportPurchaseInventoryDetailDTO item : dataPage.getItems()) {
                item.setInventoryCn(modelService.getManageName(item.getInventory()));
                item.setPartName(modelService.getPurchaseName(item.getPartId()));
            }
            model.addAttribute("inventoryPage", dataPage);
        }
        //endregion

        //region [5].物料审批（提报、物料领用、物料损坏）(提报废弃，新版本使用采购单)
        if (englishDTO.getTableName().toLowerCase().equals("transport_purchase_detail")) {
            TransportPurchaseDetailDTO purchaseDetailDTO = purchaseDetailService.getById(applyDTO.getRecordId());
            purchaseDetailDTO.setPartName(modelService.getPurchaseName(purchaseDetailDTO.getPartId()));
            purchaseDetailDTO.setReviewerCn(modelService.getUserTrueName(purchaseDetailDTO.getReviewer()));

            //采购
            if (purchaseDetailDTO.getOpType() == 1) {
                purchaseDetailDTO.setrPurchaserName(modelService.getManageName(purchaseDetailDTO.getrPurchaser()));
                purchaseDetailDTO.setrCompanyName(modelService.getCompanyName(purchaseDetailDTO.getrCompanyId()));
                purchaseDetailDTO.setrPayCompanyName(modelService.getCompanyName(purchaseDetailDTO.getrCompanyId()));
                purchaseDetailDTO.setrPayWayName(ReceiveWayEnum.getEnumByKey(purchaseDetailDTO.getrPayWay()));
            }

            //出库
            if (purchaseDetailDTO.getOpType() == 2) {
                purchaseDetailDTO.setcUserName(modelService.getUserTrueName(purchaseDetailDTO.getcUserId()));
                purchaseDetailDTO.setcOutTypeName(PurchaseDetailOutEnum.getEnumByKey(purchaseDetailDTO.getcOutType()));

                //region 获取出库明细
                TransportPurchaseDetailDTOQuery detailQuery = new TransportPurchaseDetailDTOQuery();
                detailQuery.setApplyId(applyId);
                detailQuery.setStopFlag(0);
                detailQuery.setPageSize(100);
                Page<TransportPurchaseDetailDTO> detailPage = purchaseDetailService.getForPage(detailQuery);
                for (TransportPurchaseDetailDTO item : detailPage.getItems()) {
                    TransportPurchaseDTO dto = purchaseService.getFromCacheId(item.getPartId());
                    if (dto != null) {
                        item.setPartName(dto.getPartName());
                        item.setPartNo(dto.getPartNo());
                        item.setSpecialName(dto.getSpecialName());
                    }
                }
                model.addAttribute("outDetailPage", detailPage);
                //endregion
            }

            //损坏
            if (purchaseDetailDTO.getOpType() == 3) {
                purchaseDetailDTO.setsAdminName(modelService.getUserTrueName(purchaseDetailDTO.getsAdminId()));
            }

            model.addAttribute("purchaseDetailObj", purchaseDetailDTO);
        }
        //endregion

        //region [8].采购单
        if (englishDTO.getTableName().toLowerCase().equals("transport_purchase_doc")) {
            TransportPurchaseDocDTO purchaseDocDTO = purchaseDocService.getById(applyDTO.getRecordId());
            purchaseDocDTO.setCompanyName(modelService.getCompanyName(purchaseDocDTO.getCompanyId()));
            purchaseDocDTO.setPurchaseCn(modelService.getManageName(purchaseDocDTO.getPurchaser()));
            purchaseDocDTO.setPayCompanyName(modelService.getCompanyName(purchaseDocDTO.getPayCompanyId()));
            purchaseDocDTO.setPayWayName(ReceiveWayEnum.getEnumByKey(purchaseDocDTO.getPayWay()));
            purchaseDocDTO.setExpressName(modelService.getCatalogName(purchaseDocDTO.getExpressId()));
            purchaseDocDTO.setSignCn(modelService.getManageName(purchaseDocDTO.getSignId()));
            model.addAttribute("purchaseDocObj", purchaseDocDTO);

            //region 获取采购明细
            TransportPurchaseDetailDTOQuery detailQuery = new TransportPurchaseDetailDTOQuery();
            detailQuery.setTableId(179);
            detailQuery.setPurId(purchaseDocDTO.getId());
            detailQuery.setStopFlag(0);
            detailQuery.setPageSize(100);
            Page<TransportPurchaseDetailDTO> detailPage = purchaseDetailService.getForPage(detailQuery);
            for (TransportPurchaseDetailDTO item : detailPage.getItems()) {
                TransportPurchaseDTO dto = purchaseService.getFromCacheId(item.getPartId());
                if (dto != null) {
                    item.setPartName(dto.getPartName());
                    item.setPartNo(dto.getPartNo());
                    item.setSpecialName(dto.getSpecialName());
                }
            }
            model.addAttribute("docDetailPage", detailPage);
            //endregion

            //region 获取已上传附件
            modelService.getUploadPage(model, purchaseDocDTO.getPurchaseDoc());
            //endregion
        }
        //endregion

        //region [9].出库单
        if (englishDTO.getTableName().toLowerCase().equals("transport_purchase_out")) {
            TransportPurchaseOutDTO purchaseOutDTO = purchaseOutService.getById(applyDTO.getRecordId());
            purchaseOutDTO.setReceiverCn(modelService.getUserTrueName(purchaseOutDTO.getReceiver()));
            purchaseOutDTO.setOperatorCn(modelService.getManageName(purchaseOutDTO.getOperator()));
            purchaseOutDTO.setOutTypeName(PurchaseDetailOutEnum.getEnumByKey(purchaseOutDTO.getOutType()));
            model.addAttribute("purchaseOutObj", purchaseOutDTO);

            //region 获取出库明细
            TransportPurchaseDetailDTOQuery detailQuery = new TransportPurchaseDetailDTOQuery();
            detailQuery.setTableId(205);
            detailQuery.setPurId(purchaseOutDTO.getId());
            detailQuery.setStopFlag(0);
            detailQuery.setPageSize(100);
            Page<TransportPurchaseDetailDTO> detailPage = purchaseDetailService.getForPage(detailQuery);
            for (TransportPurchaseDetailDTO item : detailPage.getItems()) {
                TransportPurchaseDTO dto = purchaseService.getFromCacheId(item.getPartId());
                if (dto != null) {
                    item.setPartName(dto.getPartName());
                    item.setPartNo(dto.getPartNo());
                    item.setSpecialName(dto.getSpecialName());
                }
            }
            model.addAttribute("outDetailPage", detailPage);
            //endregion
        }
        //endregion

        //region [10].销售订单审批
        if (englishDTO.getTableName().toLowerCase().equals("mes_sale_order")) {
            MesSaleOrderDTO saleOrderDTO = mesSaleOrderService.getById(applyDTO.getRecordId());
            saleOrderDTO.setCompanyName(modelService.getCompanyName(saleOrderDTO.getCompanyId()));
            saleOrderDTO.setEmergentLevelName(PriorityTypeEnum.getEnumByKey(saleOrderDTO.getEmergentLevel()));
            saleOrderDTO.setProduceModeName(ProduceModeEnum.getEnumByKey(saleOrderDTO.getProduceMode()));
            saleOrderDTO.setPayWayName(ReceiveWayEnum.getEnumByKey(saleOrderDTO.getPayWay()));
            saleOrderDTO.setOperatorCn(modelService.getManageName(saleOrderDTO.getOperator()));
            saleOrderDTO.setStockStatusName(MaterialReadyEnum.getEnumByKey(saleOrderDTO.getStockStatus()));
            saleOrderDTO.setStatusName(OrderStatusEnum.getEnumByKey(saleOrderDTO.getStatus()));
            model.addAttribute("saleOrderObj", saleOrderDTO);

            //region 获取订单产品明细
            MesSaleOrderDetailDTOQuery detailQuery = new MesSaleOrderDetailDTOQuery();
            detailQuery.setOrderId(saleOrderDTO.getId());
            detailQuery.setStopFlag(0);
            detailQuery.setPageSize(100);
            Page<MesSaleOrderDetailDTO> productPage = mesSaleOrderDetailService.getForPage(detailQuery);
            model.addAttribute("saleProductPage", productPage);
            //endregion

            //region 获取客户原料
            MesOrderMaterialDTOQuery materiallQuery = new MesOrderMaterialDTOQuery();
            materiallQuery.setTableId(203);
            materiallQuery.setRecordId(saleOrderDTO.getId());
            materiallQuery.setPageSize(100);
            Page<MesOrderMaterialDTO> materialPage = mesOrderMaterialService.getForPage(materiallQuery);
            for (MesOrderMaterialDTO item : materialPage.getItems()) {
                item.setGoodsTypeName(ProductTypeEnum.getEnumByKey(item.getGoodsType()));
            }
            model.addAttribute("saleMaterialPage", materialPage);
            //endregion
        }
        //endregion

        //region [11].生产订单审批
        if (englishDTO.getTableName().toLowerCase().equals("mes_produce_order")) {
            MesProduceOrderDTO produceOrderDTO = mesProduceOrderService.getById(applyDTO.getRecordId());
            produceOrderDTO.setMaterialReadyName(MaterialReadyEnum.getEnumByKey(produceOrderDTO.getMaterialReady()));
            produceOrderDTO.setOperatorCn(modelService.getManageName(produceOrderDTO.getOperator()));
            produceOrderDTO.setStatusName(OrderStatusEnum.getEnumByKey(produceOrderDTO.getStatus()));
            produceOrderDTO.setOrderTypeName(OrderTypeEnum.getEnumByKey(produceOrderDTO.getOrderType()));
            produceOrderDTO.setSnRuleName(QRCodeRuleEnum.getEnumByKey(produceOrderDTO.getSnRule()));
            produceOrderDTO.setShipName(modelService.getMesShipName(produceOrderDTO.getShipId()));
            produceOrderDTO.setProduceLineName(modelService.getMesProduceLineName(produceOrderDTO.getProduceLine()));
            model.addAttribute("produceOrderObj", produceOrderDTO);

            //region 生产销售关联订单
            MesProduceOrderSaleDTOQuery orderSaleHistoryQuery = new MesProduceOrderSaleDTOQuery();
            orderSaleHistoryQuery.setProduceId(produceOrderDTO.getId());
            orderSaleHistoryQuery.setStopFlag(0);
            orderSaleHistoryQuery.setPageSize(100);
            Page<MesProduceOrderSaleDTO> orderSaleHistoryPage = mesProduceOrderSaleService.getForPage(orderSaleHistoryQuery);
            for (MesProduceOrderSaleDTO item : orderSaleHistoryPage.getItems()) {
                MesSaleOrderDTO sale = mesSaleOrderService.getById(item.getSaleId());
                if (sale != null) {
                    item.setSaleName(sale.getOrderTitle());
                    item.setSaleNo(sale.getOrderNo());
                }

                MesSaleOrderDetailDTO detail = mesSaleOrderDetailService.getById(item.getSaleDetailId());
                if (detail != null) {
                    item.setSaleDetailName(detail.getProductName());
                    item.setSpecialName(detail.getSpecialName());
                }
            }
            model.addAttribute("produceOrderSaleList", orderSaleHistoryPage.getItems());
            //endregion

            //region 生产用料
            MesOrderMaterialDTOQuery materiallHistoryQuery = new MesOrderMaterialDTOQuery();
            materiallHistoryQuery.setTableId(191);
            materiallHistoryQuery.setRecordId(produceOrderDTO.getId());
            materiallHistoryQuery.setPageSize(100);
            Page<MesOrderMaterialDTO> materialHistoryPage = mesOrderMaterialService.getForPage(materiallHistoryQuery);
            for (MesOrderMaterialDTO item : materialHistoryPage.getItems()) {
                item.setGoodsTypeName(ProductTypeEnum.getEnumByKey(item.getGoodsType()));
            }
            model.addAttribute("produceOrderMaterialList", materialHistoryPage.getItems());
            //endregion
        }
        //endregion

        //endregion

        //region 按钮权限

        //“通过”权限：当前操作人 = 审批人 || 代理人  || 超级管理员 等3种情况
        int passBtn = 0;

        //“驳回”权限：当前操作人 = 当前流程可驳回 && （审批人 || 代理人 || 超级管理员）
        int rejectBtn = 0;

        //“撤回”权限：当前流程可撤回 && （申请人 || 超级管理员）
        //说明：“驳回” 和“撤回” 只能出现一个按钮，撤回的优化级高于驳回。（管理员除外）
        //申请人要一直显示“撤回”，但不显示驳回
        int cancelBtn = 0;

        //“回退”权限：取决于环节设置
        int returnBtn = 0;

        //“加签”权限：取决于环节设置
        int addBtn = 0;

        //“催办”权限：取决于环节设置
        int urgeBtn = 0;

        //endregion

        //region STEP 04.获取申请环节信息
        WorkflowApplyLineDTOQuery dtoQuery = new WorkflowApplyLineDTOQuery();
        dtoQuery.setApplyId(applyId);
        dtoQuery.setOrderBy("order by node_sort asc");
        Page<WorkflowApplyLineDTO> dataPage = applyLineService.getForPage(dtoQuery);

        // 实时更新列表信息
        if (dataPage != null && dataPage.getItems().size() > 0) {
            for (WorkflowApplyLineDTO item : dataPage.getItems()) {

                //当前用户是否有审批权
                boolean canApprove = false;

                //region 通过环节ID获取环节审批人/代理关联表数据
                WorkflowApplyLineUserDTOQuery relUserQuery = new WorkflowApplyLineUserDTOQuery();
                relUserQuery.setLineId(item.getId());
                Page<WorkflowApplyLineUserDTO> relPage = lineUserService.getForPage(relUserQuery);

                //用户信息
                TransportUserDTO user_player;

                //审批人
                List<String> approveList = new ArrayList<>();
                //代理人
                List<String> agentList = new ArrayList<>();
                //抄送人
                List<String> ccList = new ArrayList<>();

                for (WorkflowApplyLineUserDTO c : relPage.getItems()) {
                    user_player = userService.getFromCacheId(c.getApprover());
                    if (user_player == null) {
                        continue;
                    }

                    //判断当前环节是否有审批权限：当前环节；审批人=当前用户
                    if (item.getIsCurrent() == 1 && user_player.getId().equals(modelService.getUserIdByAdminId(curr_obj.getId()))) {
                        canApprove = true;
                    }

                    //1审批人 2代理人 3抄送人
                    if (c.getPlayerType() == 1 && !approveList.contains(user_player.getTrueName())) {
                        approveList.add(user_player.getTrueName());
                    }
                    if (c.getPlayerType() == 2 && !agentList.contains(user_player.getTrueName())) {
                        agentList.add(user_player.getTrueName());
                    }
                    if (c.getPlayerType() == 3 && !ccList.contains(user_player.getTrueName())) {
                        ccList.add(user_player.getTrueName());
                    }
                }

                //审批人
                item.setApproverName(String.join("、", approveList));

                //代理人
                item.setAgentName(String.join("、", agentList));

                //抄送人
                item.setCopyName(String.join("、", ccList));

                //endregion

                //region 当前环节信息
                if (item.getIsCurrent() == 1) {

                    //[0].“通过” 和 “驳回” 权限：当前操作人 = 审批人 || 代理人 || 超级管理员 等3种情况
                    if (canApprove || curr_obj.getIsSuper() == 1) {
                        passBtn = 1;
                        rejectBtn = 1;
                        returnBtn = 1;
                        addBtn = 1;
                        urgeBtn = 1;
                    }

                    //[1].“定制审批”环节，且不是“已开票”状态，则不显示“通过”权限

                    //[2].“驳回”权限：当前流程可驳回
                    if (item.getIsRejected() != 1) {
                        rejectBtn = 0;
                    }

                    //[3].“回退”权限
                    if (item.getIsBack() != 1) {
                        returnBtn = 0;
                    }

                    //[4].“加签”权限
                    if (item.getIsAdd() != 1) {
                        addBtn = 0;
                    }

                    //[5].“催办”权限
                    if (item.getIsUrge() != 1) {
                        urgeBtn = 0;
                    }

                    //[6].“撤回”权限（申请人在所有的环节都可以撤回）：申请人 || 超级管理员 等2种情况
                    if (Objects.equals(curr_obj.getId(), applyDTO.getApply()) || curr_obj.getIsSuper() == 1) {
                        cancelBtn = 1;
                    }

                    //[7].“驳回” 和“撤回” 只能出现一个按钮，撤回的优化级高于驳回。（管理员除外）
                    if (cancelBtn == 1 && curr_obj.getIsSuper() != 1) {
                        rejectBtn = 0;
                    }
                }
                //endregion

                //实际审批人
                if (item.getRealApproverId() > 0) {
                    item.setRealApproverName(modelService.getUserTrueName(item.getRealApproverId()));
                }

                //状态
                item.setStatusName(ApplyLineStatusEnum.getEnumByKey(item.getStatus()));

                //审批类型
                item.setApprovalTypeName(ApprovalTypeEnum.getEnumByKey(item.getApprovalType()));
            }
        }
        model.addAttribute("linePage", dataPage);
        //endregion

        model.addAttribute("cancelBtn", cancelBtn);
        model.addAttribute("passBtn", passBtn);
        model.addAttribute("rejectBtn", rejectBtn);
        model.addAttribute("returnBtn", returnBtn);
        model.addAttribute("addBtn", addBtn);
        model.addAttribute("urgeBtn", urgeBtn);

        return "basic/wfapplyline/approval-line";
    }

    //endregion

    //region 审批（工单）
    @RequestMapping(value = "/approval-line-order", method = RequestMethod.GET)
    public String approvalLineOrder(HttpServletRequest request, Model model, Integer applyId) {
        if (applyId == null || applyId == 0) {
            throw new RuntimeException("未查询到审批流程信息");
        }

        //审批ID
        model.addAttribute("applyId", applyId);

        //region STEP 01.获取申请信息
        WorkflowApplyDTO applyDTO = applyService.getById(applyId);
        if (applyDTO == null) {
            throw new RuntimeException("未查询到审批流程信息");
        }
        applyDTO.setApplyName(modelService.getManageName(applyDTO.getApply()));
        applyDTO.setStatusName(ApplyStatusEnum.getEnumByKey(applyDTO.getStatus()));
        model.addAttribute("applyObj", applyDTO);

        String pin = AdminBaseClass.getPin(request);
        AnalysisManageDTO curr_obj = manageService.getFromCachePin(pin);
        //endregion

        //region STEP 02.获取流程业务信息
        WorkflowBusinessDTO businessDTO = businessService.getById(applyDTO.getBusinessId());
        if (businessDTO == null) {
            throw new RuntimeException("未查询到流程业务信息");
        }
        businessDTO.setBusinessTypeName(BusinessTypeEnum.getEnumByKey(businessDTO.getBusinessType()));
        model.addAttribute("businessObj", businessDTO);
        //endregion

        //region STEP 03.获取具体申请业务信息
        TransportTableChineseEnglishDTO englishDTO = chineseEnglishService.getById(applyDTO.getTableId());
        if (englishDTO == null) {
            throw new RuntimeException("未查询到数据库表信息");
        }

        //region [1].工单管理
        if (englishDTO.getTableName().toLowerCase().equals("customer_work_order")) {
            //TODO
        }

        //endregion

        //endregion

        //region 按钮权限

        //“通过”权限：当前操作人 = 审批人 || 代理人  || 超级管理员 等3种情况
        int passBtn = 0;

        //“驳回”权限：当前操作人 = 当前流程可驳回 && （审批人 || 代理人 || 超级管理员）
        int rejectBtn = 0;

        //“撤回”权限：当前流程可撤回 && （申请人 || 超级管理员）
        //说明：“驳回” 和“撤回” 只能出现一个按钮，撤回的优化级高于驳回。（管理员除外）
        //申请人要一直显示“撤回”，但不显示驳回
        int cancelBtn = 0;

        //“回退”权限：取决于环节设置
        int returnBtn = 0;

        //“加签”权限：取决于环节设置
        int addBtn = 0;

        //“催办”权限：取决于环节设置
        int urgeBtn = 0;

        //endregion

        //region STEP 04.获取申请环节信息
        WorkflowApplyLineDTOQuery dtoQuery = new WorkflowApplyLineDTOQuery();
        dtoQuery.setApplyId(applyId);
        dtoQuery.setOrderBy("order by node_sort asc");
        Page<WorkflowApplyLineDTO> dataPage = applyLineService.getForPage(dtoQuery);

        // 实时更新列表信息
        if (dataPage != null && dataPage.getItems().size() > 0) {
            for (WorkflowApplyLineDTO item : dataPage.getItems()) {

                //当前用户是否有审批权
                boolean canApprove = false;

                //region 通过环节ID获取环节审批人/代理关联表数据
                WorkflowApplyLineUserDTOQuery relUserQuery = new WorkflowApplyLineUserDTOQuery();
                relUserQuery.setLineId(item.getId());
                Page<WorkflowApplyLineUserDTO> relPage = lineUserService.getForPage(relUserQuery);

                //用户信息
                TransportUserDTO user_player;

                //审批人
                List<String> approveList = new ArrayList<>();
                //代理人
                List<String> agentList = new ArrayList<>();
                //抄送人
                List<String> ccList = new ArrayList<>();

                for (WorkflowApplyLineUserDTO c : relPage.getItems()) {
                    user_player = userService.getFromCacheId(c.getApprover());
                    if (user_player == null) {
                        continue;
                    }

                    //判断当前环节是否有审批权限：当前环节；审批人=当前用户
                    if (item.getIsCurrent() == 1 && user_player.getId().equals(modelService.getUserIdByAdminId(curr_obj.getId()))) {
                        canApprove = true;
                    }

                    //1审批人 2代理人 3抄送人
                    if (c.getPlayerType() == 1 && !approveList.contains(user_player.getTrueName())) {
                        approveList.add(user_player.getTrueName());
                    }
                    if (c.getPlayerType() == 2 && !agentList.contains(user_player.getTrueName())) {
                        agentList.add(user_player.getTrueName());
                    }
                    if (c.getPlayerType() == 3 && !ccList.contains(user_player.getTrueName())) {
                        ccList.add(user_player.getTrueName());
                    }
                }

                //审批人
                item.setApproverName(String.join("、", approveList));

                //代理人
                item.setAgentName(String.join("、", agentList));

                //抄送人
                item.setCopyName(String.join("、", ccList));

                //endregion

                //region 当前环节信息
                if (item.getIsCurrent() == 1) {

                    //[0].“通过” 和 “驳回” 权限：当前操作人 = 审批人 || 代理人 || 超级管理员 等3种情况
                    if (canApprove || curr_obj.getIsSuper() == 1) {
                        passBtn = 1;
                        rejectBtn = 1;
                        returnBtn = 1;
                        addBtn = 1;
                        urgeBtn = 1;
                    }

                    //[1].“定制审批”环节
                    if (item.getApprovalType() == 2) {
                        passBtn = 0;
                    }

                    //[2].“驳回”权限：当前流程可驳回
                    if (item.getIsRejected() != 1) {
                        rejectBtn = 0;
                    }

                    //[3].“回退”权限
                    if (item.getIsBack() != 1) {
                        returnBtn = 0;
                    }

                    //[4].“加签”权限
                    if (item.getIsAdd() != 1) {
                        addBtn = 0;
                    }

                    //[5].“催办”权限
                    if (item.getIsUrge() != 1) {
                        urgeBtn = 0;
                    }

                    //[6].“撤回”权限（申请人在所有的环节都可以撤回）：申请人 || 超级管理员 等2种情况
                    if (Objects.equals(curr_obj.getId(), applyDTO.getApply()) || curr_obj.getIsSuper() == 1) {
                        cancelBtn = 1;
                    }

                    //[7].“驳回” 和“撤回” 只能出现一个按钮，撤回的优化级高于驳回。（管理员除外）
                    if (cancelBtn == 1 && curr_obj.getIsSuper() != 1) {
                        rejectBtn = 0;
                    }
                }
                //endregion

                //实际审批人
                if (item.getRealApproverId() > 0) {
                    item.setRealApproverName(modelService.getUserTrueName(item.getRealApproverId()));
                }

                //状态
                item.setStatusName(ApplyLineStatusEnum.getEnumByKey(item.getStatus()));

                //审批类型
                item.setApprovalTypeName(ApprovalTypeEnum.getEnumByKey(item.getApprovalType()));
            }
        }
        model.addAttribute("linePage", dataPage);
        //endregion

        model.addAttribute("cancelBtn", cancelBtn);
        model.addAttribute("passBtn", passBtn);
        model.addAttribute("rejectBtn", rejectBtn);
        model.addAttribute("returnBtn", returnBtn);
        model.addAttribute("addBtn", addBtn);
        model.addAttribute("urgeBtn", urgeBtn);

        //审批权限
        model.addAttribute("approvalAuth", modelService.getLookAllApprovalAuthor(pin));

        //位置隐私权限
        model.addAttribute("privacyAuth", modelService.getLookAllPrivacyAuthor(pin));

        return "customer/elecorder-approval/approval-line";
    }
    //endregion

    //region 执行审批

    /**
     * 执行审批 ajax异步
     *
     * @param applyId    审批ID
     * @param id         lineId，环节ID
     * @param status     状态
     * @param remark     审批意见
     * @param addApprove 加签审批人
     * @param backLineId 回退ID
     * @return map
     */
    @RequestMapping(value = "/execApprove", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> execApprove(HttpServletRequest request, Integer applyId, Integer id, Integer status, String remark,
                                           Integer addApprove, Integer backLineId) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("returnCode", 0);

        try {

            //region 这里加业务判断
            WorkflowApplyDTO applyDTO = applyService.getById(applyId);
            TransportTableChineseEnglishDTO englishDTO = chineseEnglishService.getById(applyDTO.getTableId());
            if (englishDTO == null) {
                throw new RuntimeException("未查询到数据库表信息");
            }

            //region [01].采购单：未入库的单据不能进行最后一步完成审批
            if (englishDTO.getTableName().toLowerCase().equals("transport_purchase_doc")) {
                //是否是最后一步
                WorkflowApplyLineDTO lineDTO = applyLineService.getById(id);
                if (lineDTO.getNodeTitle().equals("采购完成")) {
                    //判断当前采购单状态是否是10
                    TransportPurchaseDocDTO purchaseDocDTO = purchaseDocService.getById(applyDTO.getRecordId());
                    if (purchaseDocDTO.getStatus() > -1 && purchaseDocDTO.getStatus() < 10) {
                        map.put("returnCode", 0);
                        map.put("returnMessage", "物料未入库，不能进行此操作！");
                        return map;
                    }
                }
            }
            //endregion

            //endregion

            //获取当前审批人
            String pin = AdminBaseClass.getPin(request);
            AnalysisManageDTO curr_obj = manageService.getFromCachePin(pin);

            Boolean isNext = transactionService.approvelApply(id, status, remark, curr_obj.getId(), addApprove, backLineId);
            if (isNext) {
                map.put("returnCode", 1);
            } else {
                map.put("returnCode", 0);
                map.put("returnMessage", "审批出错，数据已恢复！");
            }
        } catch (Exception e) {
            //清空map
            map.clear();
            map.put("returnMessage", e.getMessage());
        }

        return map;
    }

    //endregion

    //region 加签

    //加签
    @RequestMapping(value = "/addApprove", method = RequestMethod.POST)
    public String addApprove() {
        return "basic/wfapplyline/add-approve-modal";
    }
    //endregion

    //region 回退

    //获取可被回退的环节

    /**
     * 获取可被回退的环节
     *
     * @param model   model
     * @param applyId 审批ID
     * @param lineId  当前环节ID
     * @return json
     */
    @RequestMapping(value = "/getApproveLine", method = RequestMethod.POST)
    public String getApproveLine(Model model, Integer applyId, Integer lineId) {
        if (applyId == null || applyId == 0) {
            throw new RuntimeException("未查询到审批流程信息");
        }

        WorkflowApplyLineDTO lineDTO = applyLineService.getById(lineId);

        WorkflowApplyLineDTOQuery dtoQuery = new WorkflowApplyLineDTOQuery();
        dtoQuery.setApplyId(applyId);
        dtoQuery.setIsCanBack(1);
        dtoQuery.setBeforeNodeSort(lineDTO.getNodeSort() - 1);
        dtoQuery.setOrderBy("order by node_sort asc");
        Page<WorkflowApplyLineDTO> dataPage = applyLineService.getForPage(dtoQuery);
        model.addAttribute("canBackPage", dataPage);

        return "basic/wfapplyline/return-approve-modal";
    }

    //endregion

    //region 催办
    @RequestMapping(value = "/urgeMessage", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> urgeMessage(Integer lineId) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("returnCode", 1);
        map.put("returnMessage", "催办成功！");

        return map;
    }
    //endregion

}